"""
设备同步调度服务
"""
import asyncio
from typing import Dict, Any
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from core.database import SessionLocal
from services.integration.wvp_integration_service import WVPIntegrationService
import structlog

logger = structlog.get_logger(__name__)


class SyncScheduler:
    """同步调度器"""
    
    def __init__(self):
        self.running = False
        self.sync_interval = 300  # 5分钟同步一次
        self.status_update_interval = 60  # 1分钟更新一次状态
        self._sync_task: asyncio.Task = None
        self._status_task: asyncio.Task = None
        self.last_sync_time: datetime = None
        self.last_status_update_time: datetime = None
        self.sync_stats = {
            "total_syncs": 0,
            "successful_syncs": 0,
            "failed_syncs": 0,
            "last_sync_result": None
        }
    
    async def start(self):
        """启动调度器"""
        if self.running:
            logger.warning("同步调度器已在运行")
            return
        
        self.running = True
        logger.info("启动WVP-Pro同步调度器")
        
        # 启动同步任务
        self._sync_task = asyncio.create_task(self._sync_loop())
        self._status_task = asyncio.create_task(self._status_update_loop())
    
    async def stop(self):
        """停止调度器"""
        if not self.running:
            return
        
        self.running = False
        logger.info("停止WVP-Pro同步调度器")
        
        # 取消任务
        if self._sync_task:
            self._sync_task.cancel()
            try:
                await self._sync_task
            except asyncio.CancelledError:
                pass
        
        if self._status_task:
            self._status_task.cancel()
            try:
                await self._status_task
            except asyncio.CancelledError:
                pass
    
    async def _sync_loop(self):
        """设备同步循环"""
        while self.running:
            try:
                await self._perform_device_sync()
                await asyncio.sleep(self.sync_interval)
            except asyncio.CancelledError:
                break
            except Exception as e:
                logger.error("设备同步循环异常", exc_info=e)
                await asyncio.sleep(60)  # 出错后等待1分钟再重试
    
    async def _status_update_loop(self):
        """状态更新循环"""
        while self.running:
            try:
                await self._perform_status_update()
                await asyncio.sleep(self.status_update_interval)
            except asyncio.CancelledError:
                break
            except Exception as e:
                logger.error("状态更新循环异常", exc_info=e)
                await asyncio.sleep(30)  # 出错后等待30秒再重试
    
    async def _perform_device_sync(self):
        """执行设备同步"""
        try:
            db = SessionLocal()
            try:
                service = WVPIntegrationService(db)
                
                # 测试WVP-Pro连接
                if not await service.test_wvp_connection():
                    logger.warning("WVP-Pro连接失败，跳过设备同步")
                    self.sync_stats["failed_syncs"] += 1
                    return
                
                # 执行设备同步
                result = await service.sync_devices_from_wvp()
                
                self.sync_stats["total_syncs"] += 1
                self.sync_stats["successful_syncs"] += 1
                self.sync_stats["last_sync_result"] = result
                self.last_sync_time = datetime.now()
                
                logger.info("定时设备同步完成", **result)
                
            finally:
                db.close()
                
        except Exception as e:
            self.sync_stats["total_syncs"] += 1
            self.sync_stats["failed_syncs"] += 1
            logger.error("定时设备同步失败", exc_info=e)
    
    async def _perform_status_update(self):
        """执行状态更新"""
        try:
            db = SessionLocal()
            try:
                service = WVPIntegrationService(db)
                
                # 测试WVP-Pro连接
                if not await service.test_wvp_connection():
                    logger.debug("WVP-Pro连接失败，跳过状态更新")
                    return
                
                # 执行状态更新
                result = await service.update_camera_status_from_wvp()
                self.last_status_update_time = datetime.now()
                
                if result["updated"] > 0:
                    logger.info("定时状态更新完成", **result)
                
            finally:
                db.close()
                
        except Exception as e:
            logger.error("定时状态更新失败", exc_info=e)
    
    async def force_sync(self) -> Dict[str, Any]:
        """强制执行一次同步"""
        try:
            db = SessionLocal()
            try:
                service = WVPIntegrationService(db)
                
                # 测试连接
                if not await service.test_wvp_connection():
                    return {
                        "success": False,
                        "message": "WVP-Pro连接失败",
                        "timestamp": datetime.now().isoformat()
                    }
                
                # 执行同步
                result = await service.sync_devices_from_wvp()
                
                self.sync_stats["total_syncs"] += 1
                self.sync_stats["successful_syncs"] += 1
                self.sync_stats["last_sync_result"] = result
                self.last_sync_time = datetime.now()
                
                return {
                    "success": True,
                    "message": "强制同步完成",
                    "result": result,
                    "timestamp": datetime.now().isoformat()
                }
                
            finally:
                db.close()
                
        except Exception as e:
            self.sync_stats["total_syncs"] += 1
            self.sync_stats["failed_syncs"] += 1
            logger.error("强制同步失败", exc_info=e)
            
            return {
                "success": False,
                "message": f"强制同步失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }
    
    async def force_status_update(self) -> Dict[str, Any]:
        """强制执行一次状态更新"""
        try:
            db = SessionLocal()
            try:
                service = WVPIntegrationService(db)
                
                # 测试连接
                if not await service.test_wvp_connection():
                    return {
                        "success": False,
                        "message": "WVP-Pro连接失败",
                        "timestamp": datetime.now().isoformat()
                    }
                
                # 执行状态更新
                result = await service.update_camera_status_from_wvp()
                self.last_status_update_time = datetime.now()
                
                return {
                    "success": True,
                    "message": "强制状态更新完成",
                    "result": result,
                    "timestamp": datetime.now().isoformat()
                }
                
            finally:
                db.close()
                
        except Exception as e:
            logger.error("强制状态更新失败", exc_info=e)
            
            return {
                "success": False,
                "message": f"强制状态更新失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }
    
    def get_status(self) -> Dict[str, Any]:
        """获取调度器状态"""
        return {
            "running": self.running,
            "sync_interval": self.sync_interval,
            "status_update_interval": self.status_update_interval,
            "last_sync_time": self.last_sync_time.isoformat() if self.last_sync_time else None,
            "last_status_update_time": self.last_status_update_time.isoformat() if self.last_status_update_time else None,
            "sync_stats": self.sync_stats,
            "next_sync_time": (
                self.last_sync_time + timedelta(seconds=self.sync_interval)
            ).isoformat() if self.last_sync_time else None,
            "next_status_update_time": (
                self.last_status_update_time + timedelta(seconds=self.status_update_interval)
            ).isoformat() if self.last_status_update_time else None
        }
    
    def update_config(self, sync_interval: int = None, status_update_interval: int = None):
        """更新配置"""
        if sync_interval is not None and sync_interval > 0:
            self.sync_interval = sync_interval
            logger.info(f"设备同步间隔更新为{sync_interval}秒")
        
        if status_update_interval is not None and status_update_interval > 0:
            self.status_update_interval = status_update_interval
            logger.info(f"状态更新间隔更新为{status_update_interval}秒")


# 全局调度器实例
_scheduler: SyncScheduler = None


def get_sync_scheduler() -> SyncScheduler:
    """获取同步调度器实例"""
    global _scheduler
    
    if _scheduler is None:
        _scheduler = SyncScheduler()
    
    return _scheduler


async def start_sync_scheduler():
    """启动同步调度器"""
    scheduler = get_sync_scheduler()
    await scheduler.start()


async def stop_sync_scheduler():
    """停止同步调度器"""
    scheduler = get_sync_scheduler()
    await scheduler.stop()